#include "../util/TcpListener.h"
#include "../dsm/Dsm.h"
#include "Types.h"
#include "colors.h"
#include <stdlib.h>

#define BUFFER_SIZE 1024

PracticaCaso::DsmDriver * driver;

extern "C" {
	#include </usr/include/signal.h>
	#include <sys/time.h>
}

void usage() {
	cout << "Usage: DsmTimeServer <dsm-server-port>" << endl;
	exit(1);
}

void ctrl_c(int)
{
	printf("\nCTRL-C was pressed...\n");
	driver->dsm_free("PLAYER1");
	driver->dsm_free("PLAYER2");
	delete driver;
	exit(0);

}

void showBoard(Board b) //SHOWS THE BOARD IN THE TERMINAL
{
	cout << "  1 2 3 4 5 6 7 8 9" << endl;
	cout << "  __________________" << endl;
	for(int i = 0; i < 9; i++)
	{
		cout << (i+1) <<"|";
		for(int j = 0; j < 9; j++)
		{
			if(b[i][j].opened == true)
			{
				if(b[i][j].treasure == true)
					cout << "T ";
				else
					cout << b[i][j].around << " ";
			}
		}
		
		cout << "|" << endl;
	}
	cout << "  __________________" << endl;
}


int main(int argc, char** argv) {

	signal(SIGINT,ctrl_c);
	if (argc != 2) {
		usage();
	}

	driver = new PracticaCaso::DsmDriver("127.0.0.1", atoi(argv[1]), "dsm.deusto.es");
	PracticaCaso::DsmData data;
	driver->get_nid();
	Board* board;
	int playerNum;
	int turn;
	int myTurn;
	int control;
	bool playing = true;
	Move m;
	string myCell;
	cout << GREEN_BOLD << "WELCOME TO TREASURE DIGGER 2 PLAYERS!" << COL_RESET << endl;
	try
	{
		data = driver->dsm_get("PLAYER_NUM");
		playerNum = *((int* )data.addr);

		if(playerNum == 2) //The are currently 2 players playing
		{
			cout << "The are already 2 players Playing. Please wait to end this match and try it again..." << endl;
			exit(0);
		}
		if(playerNum == 0) //The player is the first one
		{
			myTurn = 1;
			myCell = "PLAYER1";
		}
		else //The player is the second player
		{
			myTurn = 2;
			myCell = "PLAYER2";
		}
		driver->dsm_put("PLAYER_NUM",(void *)&myTurn, sizeof(myTurn));
		cout << "You are the Player " << myTurn << endl;
		driver->dsm_malloc(myCell,sizeof(m));

	}catch(DsmException dsme)
	{
		cout << "The Game Server is not operative right now, please try it again in few seconds..." << endl;
		exit(0);
	}
	try
	{
		while(playing)
		{
			
			do
			{	
				data = driver->dsm_get("TURN");
				turn = *((int* )data.addr);
				if(turn != myTurn)
				{
					cout << "Waiting For the Other Player" << endl;
					driver->dsm_wait("TURN"); //Waits the Players turn
				}
				data = driver->dsm_get("TURN");
				turn = *((int* )data.addr);
			}while(turn != myTurn);

			data = driver->dsm_get("BOARD"); //Gets the Board to see the movement of the other player
			
			//cout << "aqui" << endl;
			/*
			board = (Board*)data.addr;
			{ 	
				Board b = board[0];
				showBoard(b);
			}
*/
			data = driver->dsm_get("CONTROL");//Gets Control to see if the other player winned or lossed
			control = *((int* )data.addr);
			if (control == 1)
			{
				cout << GREEN_BOLD << "YOU WIN" << COL_RESET << endl;
				break;
				
			}
			if (control == 2)
			{
				cout << RED_BOLD << "YOU LOSE" << COL_RESET << endl;
				break;
			}			
			
			cout << "It's your turn" << endl;
			cout << "Enter the coordinates (1-9) separated by a space (f.e.: \"1 1\"): ";
			cin >> m.x >> m.y;
			m.x--;
			m.y--;

			driver->dsm_put(myCell, (void *)&m, sizeof(m)); //Writes the players movement
			sleep(1); //We wait because there is an error and doesn't wait in the next sentence
			driver->dsm_wait("BOARD");
			data = driver->dsm_get("BOARD"); //Gets the board refreshed with the players movement
			board = (Board*)data.addr;
			/*
			{ 
				cout << "Actual Board:" << endl;
				Board b = board[0];
				showBoard(b);
			}
			*/			
			data = driver->dsm_get("CONTROL"); //Checks if the player winned or lossed
			control = *((int* )data.addr);
			if (control == 1)
			{
				cout << GREEN_BOLD << "YOU WIN" << COL_RESET << endl;
				playing = false;
			}
			if (control == 2)
			{
				cout << RED_BOLD << "YOU LOSE" << COL_RESET << endl;
				playing = false;
			}
		}


		driver->dsm_free("PLAYER1");
		driver->dsm_free("PLAYER2");

	}catch(DsmException dsme)
	{
	}		
}

